import pandas as pd
import matplotlib.pyplot as plt
import math
import numpy as np

excel_name = input("请输入表格名称(SampleTarget,SampleTarget1,SampleTarget2):")
if excel_name == "SampleTarget2":
    SampleTarget = pd.read_csv("./SampleTarget2.csv", index_col=[0, 1])


    def target2_to_pnl(name):
        df = pd.read_feather("./1m/{}.ft".format(name))
        clz = df.loc[:, ["trading_day", "timestamp", "clz"]]
        clz.set_index(["trading_day", "timestamp"], inplace=True)
        # print(clz)

        SampleTarget_future = SampleTarget.loc[:, name]
        df1 = clz.join(SampleTarget_future)

        count = 0  #如果有目标仓位，没有期货价格，且之前均无价格，则忽略
        while math.isnan(df1.iloc[count][1]):
            count += 1
        df1 = df1[count:]
        # print(df1)

        pnl = [0 - abs(df1.iloc[0][1]) * 0.0003]  #初始pnl为建仓费用
        turnover = [abs(df1.iloc[0][1])]  #初始turnover为开始建仓的总计花费

        lst_clz = list(df1["clz"])
        lst_name = list(df1[name])
        for i in range(len(lst_name)):
            if math.isnan(lst_name[i]):  #补充没有目标仓位的值，补充值为当前手数乘以当前价格，达到“仓位随价格相应变动”的效果
                lst_name[i] = lst_name[i - 1] / lst_clz[i - 1] * lst_clz[i]
        df1["clz"].to_csv("lst_clz.csv")
        a = pd.DataFrame(lst_name)
        a.to_csv("lst_name.csv")

        for i in range(len(lst_name) - 1):  #计算turnover=当天仓位-昨天手数*今天价格，和pnl=昨天手数*今天价格-昨天仓位-交易费用
            Tmp = abs(lst_name[i + 1] - lst_name[i] / lst_clz[i] * lst_clz[i + 1])
            turnover.append(Tmp)
            fee = Tmp * 0.0003
            pnl.append(lst_name[i] / lst_clz[i] * lst_clz[i + 1] - lst_name[i] - fee)

        df1["pnl_{}".format(name)] = pnl
        df1["turnover_{}".format(name)] = turnover

        return df1["pnl_{}".format(name)], df1["turnover_{}".format(name)], df1[name]


    df_pnl = target2_to_pnl(SampleTarget.columns[0])[0]  # 提取每一种期货的pnl并放在一个dataframe里
    for x in SampleTarget.columns[1:]:
        df_pnl = pd.concat([df_pnl, target2_to_pnl(x)[0]], axis=1)

    df_pnl = df_pnl.sort_index(axis=0).fillna(0)  # 求夏普率
    df_pnl["sum"] = df_pnl.sum(axis=1)
    pnl_std = df_pnl["sum"].replace(0, np.nan).std()
    Sharp_ratio = df_pnl["sum"].replace(0, np.nan).mean() / pnl_std * 15.8
    print(Sharp_ratio)

    df_turnover = target2_to_pnl(SampleTarget.columns[0])[1]  # 提取每一种期货的turnover并放在一个dataframe里
    for x in SampleTarget.columns[1:]:
        df_turnover = pd.concat([df_turnover, target2_to_pnl(x)[1]], axis=1)
    index_turnover = df_turnover.mean(1).mean()  # 得到TurnOver指标
    print(index_turnover)

    df_leverage = target2_to_pnl(SampleTarget.columns[0])[2]  # 提取每一种期货的leverage并放在一个dataframe里
    for x in SampleTarget.columns[1:]:
        df_leverage = pd.concat([df_leverage, target2_to_pnl(x)[2]], axis=1)
    index_AvgLeverage = df_leverage.mean(1).mean()  # 得到AvgLeverage指标
    print(index_AvgLeverage)

    lst_pnl = list(df_pnl["sum"])  # 计算累计pnl
    pnl_net = np.cumsum(lst_pnl)

    ax = plt.figure().add_subplot()  # 画图像
    ax.set_title("SharpRatio:" + str(Sharp_ratio) + ",TurnOver:" + str(index_turnover) + ",AvgLeverage:" + str(
        index_AvgLeverage))
    ax.plot(pnl_net, "red", label="pnl_net")
    ax.legend()
    plt.xticks([])
    plt.show()


else:
    if excel_name == "SampleTarget":
        SampleTarget = pd.read_csv("./SampleTarget.csv", index_col=0)
    elif excel_name == "SampleTarget1":
        SampleTarget = pd.read_csv("./SampleTarget1.csv", index_col=0)
        SampleTarget/=1000000
    else:
        print("wrong")
        exit()


    def Future_name_to_pnl(name):
        df=pd.read_feather("./1m/{}.ft".format(name))  #按照期货名称提取
        clz = df[df["timestamp"]== 145900].loc[:,["trading_day","clz"]]
        # print(clz.iloc[0][0])
        clz.set_index("trading_day",inplace=True)
        # print(clz)

        SampleTarget_future = SampleTarget.loc[:,name]
        SampleTarget_future = pd.DataFrame(SampleTarget_future)
        df1 =SampleTarget_future.join(clz).fillna(method = "ffill",axis = 0)

        count = 0  #如果有目标仓位，没有期货价格，且之前均无价格，则忽略
        while math.isnan(df1.iloc[count][1]):
            count+=1
        df1 = df1[count:]

        pnl = [0-abs(df1.iloc[0][0])*0.0003]  #初始pnl为建仓费用
        turnover = [abs(df1.iloc[0][0])]  #初始turnover为开始建仓的总计花费
        # print(df1)

        for i in range(len(df1)-1):  #计算turnover=当天仓位-昨天手数*今天价格，和pnl=昨天手数*今天价格-昨天仓位-交易费用
            Tmp = abs(df1.iloc[i + 1][0] - df1.iloc[i][0] / df1.iloc[i][1] * df1.iloc[i + 1][1])
            turnover.append(Tmp)
            fee = Tmp * 0.0003
            pnl.append(df1.iloc[i][0] / df1.iloc[i][1] * df1.iloc[i + 1][1] - df1.iloc[i][0] - fee)

        df1["pnl_{}".format(name)] = pnl
        df1["turnover_{}".format(name)] = turnover

        return df1["pnl_{}".format(name)],df1["turnover_{}".format(name)],df1[name]



    df_pnl = Future_name_to_pnl(SampleTarget.columns[1])[0]  #提取每一种期货的pnl并放在一个dataframe里
    for x in SampleTarget.columns[2:]:
        df_pnl = pd.concat([df_pnl,Future_name_to_pnl(x)[0]],axis=1)

    df_pnl = df_pnl.sort_index(axis=0).fillna(0)  #求夏普率
    df_pnl["sum"] = df_pnl.sum(axis=1)
    pnl_std = df_pnl["sum"].std()
    Sharp_ratio = df_pnl["sum"].mean()/pnl_std*15.8
    print(Sharp_ratio)

    df_turnover = Future_name_to_pnl(SampleTarget.columns[1])[1]  #提取每一种期货的turnover并放在一个dataframe里
    for x in SampleTarget.columns[2:]:
        df_turnover = pd.concat([df_turnover,Future_name_to_pnl(x)[1]],axis=1)
    index_turnover = df_turnover.mean(1).mean()  #得到TurnOver指标
    print(index_turnover)

    df_leverage = Future_name_to_pnl(SampleTarget.columns[1])[2]  #提取每一种期货的leverage并放在一个dataframe里
    for x in SampleTarget.columns[2:]:
        df_leverage = pd.concat([df_leverage,Future_name_to_pnl(x)[2]],axis=1)
    index_AvgLeverage = df_leverage.mean(1).mean()  #得到AvgLeverage指标
    print(index_AvgLeverage)

    lst_pnl = list(df_pnl["sum"])  #计算累计pnl
    pnl_net = np.cumsum(lst_pnl)


    ax = plt.figure().add_subplot()  #画图像
    ax.set_title("SharpRatio:"+str(Sharp_ratio)+",TurnOver:"+str(index_turnover)+",AvgLeverage:"+str(index_AvgLeverage))
    ax.plot(pnl_net,"red",label = "pnl_net")
    ax.legend()
    plt.xticks([])
    plt.show()
